import keras
from keras.models import Sequential, Model
from keras.layers import Dense, Activation, Dropout, Input, Embedding, LSTM
from keras.optimizers import SGD
import keras.backend as K
import numpy as np

# model = Sequential()    # 简单的模型是 Sequential 顺序模型
# # .add() 来堆叠模型
# model.add( Dense(units=60, activation='relu', input_dim=100 ) )
# model.add( Dense(units=10, activation='softmax')  )
# # 完成了模型的构建后, 可以使用 .compile() 来配置学习过程,  # 评估标准 metrics
# model.compile(loss='categorical_crossentropy',
#               optimizer='sgd',
#               metrics=['accuracy'])     # 对于任何分类问题，你都希望将其设置为 metrics = ['accuracy']


# # 可以批量地在训练数据上进行迭代了
# model.fit(x_train,y_train,epochs=5,batch_size=32)
# # 或者，你可以手动地将批次的数据提供给模型
# model.train_on_batch(x_batch,y_batch)
# # 只需一行代码就能评估模型性能 
# loss_and_metrics = model.evaluate(x_test,y_test,batch_size=128)
# # 或者对新的数据生成预测
# classes = model.predict(x_test,batch_size=128)

# 通过将网络层实例的列表传递给 Sequential 的构造器，来创建一个 Sequential 模型
# model = Sequential( [
#     Dense(32,input_shape=(784,)),  # 等价：Dense(32, input_dim=784)
#     Activation('relu'),
#     Dense(10),
#     Activation('softmax')  ]  )

# # 也可以简单地使用 .add() 方法将各层添加到模型中
# model =Sequential()
# model.add(  Dense(32, input_dim=784)   )
# model.add(Activation('relu')  )

# 模型需要知道它所期望的输入的尺寸。
# 出于这个原因，顺序模型中的第一层（且只有第一层，因为下面的层可以自动地推断尺寸）需要接收关于其输入尺寸的信息

# # 自定义评估标准函数
# def mean_pred(y_true,y_pred):
#     return K.mean(y_pred)
# model.compile( optimizer='rmsprop',
#                 loss = 'binary_crossentropy',
#                 metrics=['accuracy',mean_pred ]  )



# # 模型训练
# model = Sequential()
# model.add( Dense(32,activation='relu', input_dim=100) )
# model.add( Dense(1, activation='sigmoid'   ) )
# model.compile( optimizer='rmsprop', loss='binary_crossentropy',
#                 metrics=['accuracy']  )

# # # 生成虚拟数据
# data = np.random.random((1000,100))
# labels = np.random.randint(2,size=(1000,1))
# # 训练模型，以 32 个样本为一个 batch 进行迭代
# model.fit(data,labels,epochs=10,batch_size=32)



# MLP  基于多层感知器 (MLP) 的 softmax 多分类
x_train = np.random.random((1000, 20))
y_train = keras.utils.to_categorical(np.random.randint(10, size=(1000, 1)), num_classes=10)
x_test = np.random.random((100, 20))
y_test = keras.utils.to_categorical(np.random.randint(10, size=(100, 1)), num_classes=10)




# Keras 函数式 API

# # 这部分返回一个张量
# inputs = Input(shape=(20,))
# # 层的实例是可调用的，它以张量为参数，并且返回一个张量
# x = Dense(64, activation='relu')(inputs)
# x = Dense(64, activation='relu')(x)
# predictions = Dense(10, activation='softmax')(x)
# # 这部分创建了一个包含输入层和三个全连接层的模型
# model = Model(inputs=inputs,  outputs=predictions)
# model.compile( optimizer='rmsprop',
#                 loss='categorical_crossentropy',
#                 metrics=['accuracy'])
# model.fit(x_train,y_train)  # 开始训练




# 具有多个输入和输出的模型。函数式 API 使处理大量交织的数据流变得容易

# 标题输入：接收一个含有 100 个整数的序列，每个整数在 1 到 10000 之间。
main_input = Input(shape=(100,),dtype='int32',name='main_input')
# Embedding 层将输入序列编码为一个稠密向量的序列，
# 每个向量维度为 512
x = Embedding(output_dim=512,input_dim=10000,input_length=100)(main_input)

# LSTM 层把向量序列转换成单个向量，
# 它包含整个序列的上下文信息
lstm_out = LSTM(32)(x)

auxiliary_output = Dense(1,activation='sigmoid',name='aux_output')(lstm_out)



print("Done")